package spit;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridLayout;
import java.awt.GridBagLayout;
import java.awt.LayoutManager;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;

import com.sun.awt.AWTUtilities;

public class Game extends JFrame {
		
	private static final LayoutManager GridBagLayout = null;
	
	JLabel tableSurface;
	
	JPanel gameBoard;
	JPanel sideBoard;
	
	JButton originalShuffleButton;
	JButton splitButton;
	JButton playerShuffleButton;
	JButton dealButton;
	JButton spitButton;
	
	volatile CardSlot playerOneDeck;
	volatile CardSlot playerTwoDeck;
	
	CardSlot playerOnePileOne;
	CardSlot playerOnePileTwo;
	CardSlot playerOnePileThree;
	CardSlot playerOnePileFour;
	CardSlot playerOnePileFive;
	
	ArrayList<CardSlot> playerOnePiles;
	volatile ArrayList<CardSlot> playerTwoPiles;
	volatile ArrayList<CardSlot> spitPiles;
	
	CardSlot playerTwoPileOne;
	CardSlot playerTwoPileTwo;
	CardSlot playerTwoPileThree;
	CardSlot playerTwoPileFour;
	CardSlot playerTwoPileFive;
	
	CardSlot spitPileOne;
	CardSlot spitPileTwo;
	CardSlot spitPileThree;
	
	CardSlot originalDeck;
	
	
	Card cardInHand;
	JPanel handPanel;
	CardSlot previousSlotTouched;
	
	PickUpListener pickUpListener;
	HoldListener holdListener;
	PutDownListener putDownListener;
	PileChooserListener pileChooserListener;
	
	boolean originalDeckDealt;
	volatile boolean playerDecksSpit;
	volatile boolean gameIsOn;
	
	SpitPlayer spitPlayer;
	
	Thread aiThread;
	
	InterRoundPanel interRoundPanel;
	
	EndGamePanel endGamePanel;
	
	public Game()
	{		
		
		//this.setLayout(new GridBagLayout());
		
		tableSurface = new JLabel(new ImageIcon("src/res/wood.gif"));
		tableSurface.setPreferredSize(new Dimension(800, 600));
		//tableSurface.setOpaque(false);
		tableSurface.setLayout(new GridBagLayout());
			
		createGameBoard();
		createSideBoard();

		
		playerOnePiles = new ArrayList<>();
		playerOnePiles.add(playerOnePileOne);
		playerOnePiles.add(playerOnePileTwo);
		playerOnePiles.add(playerOnePileThree);
		playerOnePiles.add(playerOnePileFour);
		playerOnePiles.add(playerOnePileFive);
		
		playerTwoPiles = new ArrayList<>();
		playerTwoPiles.add(playerTwoPileOne);
		playerTwoPiles.add(playerTwoPileTwo);
		playerTwoPiles.add(playerTwoPileThree);
		playerTwoPiles.add(playerTwoPileFour);
		playerTwoPiles.add(playerTwoPileFive);
		
		spitPiles = new ArrayList<>();
		spitPiles.add(spitPileOne);
		spitPiles.add(spitPileTwo);
		
		//tableSurface.setBounds(0, 0, tableSurface.getWidth(), tableSurface.getHeight());
		this.add(tableSurface);
		
		//this.getGlassPane().setVisible(true);
		//this.getGlassPane()
		
		gameIsOn = false;
		
		//System.out.println(this.getComponentAt(0).getComponentCount());
		spitPlayer = new SpitPlayer(this);
		Thread aiThread = new Thread(spitPlayer);
		aiThread.start();
		
		this.pack();
		
		createHandPanel();
		createInterRoundPanel();
		createEndGamePanel();
		
		
		
    }
	
	public void createGameBoard()
	{
		originalDeckDealt = false;
		
		playerOneDeck = new CardSlot();
		playerTwoDeck = new CardSlot();
		
		playerOnePileOne = new CardSlot();
		playerOnePileTwo = new CardSlot();
		playerOnePileThree = new CardSlot();
		playerOnePileFour = new CardSlot();
		playerOnePileFive = new CardSlot();
		
		playerTwoPileOne = new CardSlot();
		playerTwoPileTwo = new CardSlot();
		playerTwoPileThree = new CardSlot();
		playerTwoPileFour = new CardSlot();
	    playerTwoPileFive = new CardSlot();
		
		spitPileOne = new CardSlot();
		spitPileTwo = new CardSlot();
		spitPileThree = new CardSlot();
		
		gameBoard = new JPanel();
		gameBoard.setOpaque(false);
		gameBoard.setLayout(new GridLayout(5, 5));
		
		gameBoard.add(createFillerPanel());
		gameBoard.add(createFillerPanel());
		gameBoard.add(createFillerPanel());
		gameBoard.add(playerTwoDeck);
		gameBoard.add(createFillerPanel());
		
		gameBoard.add(playerTwoPileFive);
		gameBoard.add(playerTwoPileFour);
		gameBoard.add(playerTwoPileThree);
		gameBoard.add(playerTwoPileTwo);
		gameBoard.add(playerTwoPileOne);
		
		gameBoard.add(createFillerPanel());
		gameBoard.add(spitPileOne);
		gameBoard.add(spitPileThree);
		gameBoard.add(spitPileTwo);
		gameBoard.add(createFillerPanel());
		
		gameBoard.add(playerOnePileOne);
		gameBoard.add(playerOnePileTwo);
		gameBoard.add(playerOnePileThree);
		gameBoard.add(playerOnePileFour);
		gameBoard.add(playerOnePileFive);
		
		gameBoard.add(createFillerPanel());
		gameBoard.add(playerOneDeck);
		gameBoard.add(createFillerPanel());
		gameBoard.add(createFillerPanel());
		gameBoard.add(createFillerPanel());
		
		GridBagConstraints myConstraint = new GridBagConstraints();
		myConstraint.gridwidth = 5;
		myConstraint.weightx = 5;
		
		
		tableSurface.add(gameBoard, myConstraint);
	
		addCardSlotEvents();
		
		this.pack();
		this.revalidate();
		this.repaint();
		
		
	}
	
	public JPanel createFillerPanel()
	{
		JPanel filler = new JPanel();
		filler.setOpaque(false);
		
		return filler;
	}
	
	public void addCardSlotEvents()
	{
		pickUpListener = new PickUpListener();

		playerOnePileOne.addMouseListener(pickUpListener);
		playerOnePileTwo.addMouseListener(pickUpListener);
		playerOnePileThree.addMouseListener(pickUpListener);
		playerOnePileFour.addMouseListener(pickUpListener);
		playerOnePileFive.addMouseListener(pickUpListener);
		//playerTwoPileOne.addMouseListener(pickUpListener);
		//playerTwoPileTwo.addMouseListener(pickUpListener);
		//playerTwoPileThree.addMouseListener(pickUpListener);
		//playerTwoPileFour.addMouseListener(pickUpListener);
		//playerTwoPileFive.addMouseListener(pickUpListener);
		
	}
	
	public void createSideBoard()
	{
		originalDeck = new CardSlot();
		originalDeck.setAsFreshDeck();
		
		sideBoard = new JPanel();
		sideBoard.setOpaque(false);
		sideBoard.setLayout(new BoxLayout(sideBoard, BoxLayout.PAGE_AXIS));
		
		
		sideBoard.add(createOrigDeckHandlers());
		sideBoard.add(originalDeck);
		sideBoard.add(Box.createRigidArea(new Dimension(0, 20)));
		sideBoard.add(createPlayerDeckHandlers());

		
		GridBagConstraints myConstraint = new GridBagConstraints();
		myConstraint.gridwidth = 1;
		myConstraint.weightx = 1;
		
		
		tableSurface.add(sideBoard, myConstraint);
		

		this.revalidate();
		this.repaint();
		
	}
	
	
	public JPanel createOrigDeckHandlers()
	{
		
		JPanel origDeckHandlerPanel = new JPanel();
		origDeckHandlerPanel.setBackground(Color.WHITE);
		origDeckHandlerPanel.setOpaque(true);
		origDeckHandlerPanel.setLayout(new BoxLayout(origDeckHandlerPanel, BoxLayout.PAGE_AXIS));
		origDeckHandlerPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		
		JLabel label = new JLabel("Original Deck");
		label.setAlignmentX(CENTER_ALIGNMENT);
		
		origDeckHandlerPanel.add(label);
		origDeckHandlerPanel.add(createOrigShuffleButton());
		origDeckHandlerPanel.add(createSplitButton());
		
		return origDeckHandlerPanel;
	}
	
	public JPanel createPlayerDeckHandlers()
	{
		JPanel playerDeckHandlerPanel = new JPanel();
		playerDeckHandlerPanel.setOpaque(true);
		playerDeckHandlerPanel.setBackground(Color.WHITE);
		playerDeckHandlerPanel.setLayout(new BoxLayout(playerDeckHandlerPanel, BoxLayout.PAGE_AXIS));
		playerDeckHandlerPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		
		JLabel label = new JLabel("Player Decks");

		label.setAlignmentX(CENTER_ALIGNMENT);
		
		playerDeckHandlerPanel.add(label);
		playerDeckHandlerPanel.add(createPlayerShuffleButton());
		playerDeckHandlerPanel.add(createDealButton());
		playerDeckHandlerPanel.add(createSpitButton());
		
		return playerDeckHandlerPanel;
	}
	
	public JButton createOrigShuffleButton()
	{
		originalShuffleButton = new JButton("Shuffle");
		originalShuffleButton.setAlignmentX(CENTER_ALIGNMENT);
		
		class ShuffleButtonListener implements ActionListener
		{
			public void actionPerformed(ActionEvent e) 
			{
				if (!originalDeckDealt)
				{
					originalDeck.shuffle();
				}
				
				Game.this.revalidate();
				Game.this.repaint();
				
				splitButton.setEnabled(true);
				
			}
			
		}
		
		ShuffleButtonListener shuffleButtonListener = new ShuffleButtonListener();
		originalShuffleButton.addActionListener(shuffleButtonListener);
		
		
		return originalShuffleButton;
	}
	
	public JButton createSplitButton()
	{
		splitButton = new JButton("Split");
	    splitButton.setAlignmentX(CENTER_ALIGNMENT);
		
		class SplitButtonListener implements ActionListener
		{
			public void actionPerformed(ActionEvent e) 
			{
				//if (!originalDeckDealt)
				//{
					originalDeck.split(playerOneDeck, playerTwoDeck);
					Game.this.revalidate();
					Game.this.repaint();
					
				//}
				
				originalDeckDealt = true;
				
				originalShuffleButton.setEnabled(false);
				splitButton.setEnabled(false);

				playerShuffleButton.setEnabled(true);
				
			}
			
		}
		
		SplitButtonListener splitButtonListener = new SplitButtonListener();
		splitButton.addActionListener(splitButtonListener);
		
	    splitButton.setEnabled(false);
	    
		return splitButton;
	}
	
	public JButton createPlayerShuffleButton()
	{
		playerShuffleButton = new JButton("Shuffle");
		playerShuffleButton.setAlignmentX(CENTER_ALIGNMENT);
		
		class ShuffleButtonListener implements ActionListener
		{
			public void actionPerformed(ActionEvent e) 
			{
				playerOneDeck.shuffle();
				playerTwoDeck.shuffle();
				
				Game.this.revalidate();
				Game.this.repaint();
				
				dealButton.setEnabled(true);
				
			}
			
		}
		
		ShuffleButtonListener shuffleButtonListener = new ShuffleButtonListener();
		playerShuffleButton.addActionListener(shuffleButtonListener);
		
		playerShuffleButton.setEnabled(false);
		
		return playerShuffleButton;
	}
	
	public JButton createDealButton()
	{
		dealButton = new JButton("Deal");
		dealButton.setAlignmentX(CENTER_ALIGNMENT);
		
		class DealButtonListener implements ActionListener
		{
			public void actionPerformed(ActionEvent e) 
			{
				if (originalDeckDealt)
				{
					playerOneDeck.deal(playerOnePileOne, playerOnePileTwo, playerOnePileThree, playerOnePileFour, playerOnePileFive);
					playerTwoDeck.deal(playerTwoPileOne, playerTwoPileTwo, playerTwoPileThree, playerTwoPileFour, playerTwoPileFive);
					
					Game.this.revalidate();
					Game.this.repaint();
					
					gameIsOn = true;
					
				}
				
				//spitButton.setEnabled(true);
				
				playerShuffleButton.setEnabled(false);
				dealButton.setEnabled(false);
				

				
			}
			
		}
		
		DealButtonListener dealButtonListener = new DealButtonListener();
		dealButton.addActionListener(dealButtonListener);
		
		dealButton.setEnabled(false);
		
		return dealButton;
	}
	
	public JButton createSpitButton()
	{
		spitButton = new JButton("Spit");
		spitButton.setAlignmentX(CENTER_ALIGNMENT);
		
		class SpitButtonListener implements ActionListener
		{
			public void actionPerformed(ActionEvent e) 
			{
				//if (originalDeckDealt)
				//{
				if ( myDeckIsEmpty() && spitPileOneIsEmpty() && spitPileTwoIsEmpty() )
				{
					playerTwoDeck.spit(spitPileThree);
				}
				else if ( otherDeckIsEmpty() && spitPileOneIsEmpty() && spitPileTwoIsEmpty() )
				{
					playerOneDeck.spit(spitPileThree);
				}
				else
				{
					playerOneDeck.spit(spitPileOne);
					playerTwoDeck.spit(spitPileTwo);
				}
					
					Game.this.revalidate();
					Game.this.repaint();
					
					playerDecksSpit = true;
					
					
					spitButton.setEnabled(false);
				//}
				
				/*try {
					aiThread.sleep(1500);
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}*/
				
			}
			
		}
		
		spitButton.setEnabled(false);
		
		SpitButtonListener spitButtonListener = new SpitButtonListener();
		spitButton.addActionListener(spitButtonListener);
		
		return spitButton;
	}
	
	
	
    public void createHandPanel()
	{
		handPanel = new JPanel();
		handPanel.setLayout(null);
		
		handPanel.setOpaque(false);
		
		HoldListener holdListener = new HoldListener();
		handPanel.addMouseMotionListener(holdListener);
		
		PutDownListener putDownListener = new PutDownListener();
		handPanel.addMouseListener(putDownListener);
		
		
	}
    
    public void createInterRoundPanel()
    {

    	//System.out.print(spitPileOne.getLocation().x);
    	Point firstPoint = new Point(spitPileOne.getX() + gameBoard.getX(), spitPileOne.getY() + gameBoard.getY());
    	Point secondPoint = new Point(spitPileTwo.getX() + gameBoard.getX(), spitPileTwo.getY() + gameBoard.getY());
    	Point thirdPoint = new Point(spitPileThree.getX() + gameBoard.getX(), spitPileThree.getY() + gameBoard.getY());
    	
    	interRoundPanel = new InterRoundPanel(firstPoint, secondPoint, thirdPoint);
    	
    	interRoundPanel.setOpaque(false);
    	
    	VoidListener voidListener = new VoidListener();
    	interRoundPanel.addMouseListener(voidListener);
    	
  	
    	//HoldListener
    	
    	//interRoundPanel.setBackground(new Color(0, 0, 0, 8));
    	//interRoundPanel.setOpacity(0.5);
    	
    }
    
    public void createEndGamePanel()
    {
    	endGamePanel = new EndGamePanel();
    	
    	endGamePanel.setOpaque(false);
    	
    	VoidListener voidListener = new VoidListener();
    	interRoundPanel.addMouseListener(voidListener);
    	
    }
    public synchronized ArrayList<CardSlot> getPlayerOnePiles()
    {
    	return playerOnePiles;
    }
    
    public synchronized ArrayList<CardSlot> getPlayerTwoPiles()
    {
    	return playerTwoPiles;
    }
    
    public synchronized CardSlot getPlayerOneDeck()
    {
    	return playerOneDeck;
    }
    
    public synchronized CardSlot getPlayerTwoDeck()
    {
    	return playerTwoDeck;
    }
    
    public synchronized CardSlot getSpitPileOne()
    {
    	return spitPileOne;
    }
    
    public synchronized CardSlot getSpitPileTwo()
    {
    	return spitPileTwo;
    }
    
    public synchronized CardSlot getSpitPileThree()
    {
    	return spitPileThree;
    }
    
    
    public synchronized ArrayList<CardSlot> getSpitPiles()
    {
    	return spitPiles;
    }  


	
	public synchronized void enableSpitButton()
	{
		spitButton.setEnabled(true);

	}
	
	public synchronized void disableSpitButton()
	{
		spitButton.setEnabled(false);


	}
	
	public synchronized void enablePlayerShuffleButton()
	{
		playerShuffleButton.setEnabled(true);

	}
	
	public boolean allMyPilesAreEmpty()
	{
		
		int emptyPileCount = 0;
		for ( CardSlot pile : playerOnePiles )
		{
			if ( pile.getComponentCount() == 0 )
			{
				emptyPileCount++;
			}
		}
		
		System.out.println("empty is " + emptyPileCount);
		
		if( emptyPileCount == 5 )
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	
	public void setGameIsOn(boolean isGameOn )
	{
		gameIsOn = isGameOn;
	}
	
	public synchronized void bringUpInterRoundPanel(boolean won)
	{
		Timer timer = new Timer();
		
		interRoundPanel.signalPlayerWinIs(won);
		
		if ( won )
		{
			if ( spitPileThree.getComponentCount() > 0 )
			{
				
				System.out.println("I'm in ok dude?!!!!");
				
		    	interRoundPanel.setSpitPileOneCards(spitPileOne.getComponentCount());
		    	interRoundPanel.setSpitPileTwoCards(spitPileTwo.getComponentCount());
		    	interRoundPanel.setSpitPileThreeCards(spitPileThree.getComponentCount());
		    	
		    	Game.this.setGlassPane(interRoundPanel);
		    	Game.this.getGlassPane().setVisible(true);
		    	
				playerShuffleButton.setEnabled(true);
				spitButton.setEnabled(false);
				
				for ( final CardSlot pile : playerTwoPiles)
				{	          

			        timer.schedule( new TimerTask(){
			             public void run() { 
							addDeckToDeck(pile, playerTwoDeck);
			                 System.out.println("Wait, what..:");
			              }
			           }, 2000);
					
				}
					
		        timer.schedule( new TimerTask(){
		             public void run() { 
		 				addDeckToDeck(spitPileThree, playerTwoDeck);
		                System.out.println("Wait, what..:");
		              }
		           }, 2000);
				

				
			
				playerDecksSpit = false;
		        timer.schedule( new TimerTask(){
		             public void run() { 
		 				Game.this.getGlassPane().setVisible(false);
		                System.out.println("Wait, what..:");
		              }
		           }, 2000);

			}
			else
			{
				pileChooserListener = new PileChooserListener();
				interRoundPanel.addMouseListener(pileChooserListener);
				
		    	interRoundPanel.setSpitPileOneCards(spitPileOne.getComponentCount());
		    	interRoundPanel.setSpitPileTwoCards(spitPileTwo.getComponentCount());
		    	interRoundPanel.setSpitPileThreeCards(spitPileThree.getComponentCount());
		    	
		    	Game.this.setGlassPane(interRoundPanel);
		    	Game.this.getGlassPane().setVisible(true);
			}
		}
		else
		{
	    	interRoundPanel.setSpitPileOneCards(spitPileOne.getComponentCount());
	    	interRoundPanel.setSpitPileTwoCards(spitPileTwo.getComponentCount());
	    	interRoundPanel.setSpitPileThreeCards(spitPileThree.getComponentCount());
	    	
	    	Game.this.setGlassPane(interRoundPanel);
	    	Game.this.getGlassPane().setVisible(true);
		}

		

    	

	}
	
	public synchronized void bringUpEndGamePanel(boolean won)
	{
		endGamePanel.setWon(won);
		
    	Game.this.setGlassPane(endGamePanel);
    	Game.this.getGlassPane().setVisible(true);
	}
	
	public synchronized void addDeckToDeck(CardSlot deckToMove, CardSlot deckToAccept )
	{
		Component[] components = deckToMove.getComponents();
		
		for ( Component component : components )
		{
			Card card = (Card) component;
			if ( card.isFlippedToFront() )
			{
				card.flip();
			}
			deckToAccept.acceptCard(card);
		}
		
		this.revalidate();
		this.repaint();
	}
	
    public synchronized void setGlassInvisible()
    {
    	this.getGlassPane().setVisible(false);
    }
	
    public synchronized void addCardInHandToDeck(CardSlot playerPile)
    {
    	Component[] components = handPanel.getComponents();
    	
    	if ( components.length > 0)
    	{
    		Card card = (Card) components[0];
    		
    		card.flip();
        	playerPile.acceptCard(card);
    	}

    }
    
	public boolean myDeckIsEmpty()
	{
		CardSlot myDeck = getPlayerOneDeck();
		
		if ( myDeck.getComponentCount() == 0 )
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	
	public boolean otherDeckIsEmpty()
	{
		CardSlot otherDeck = getPlayerTwoDeck();
		
		if ( otherDeck.getComponentCount() == 0 )
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	
	public boolean spitPileOneIsEmpty()
	{
		CardSlot spitPileOne = getSpitPileOne();
		
		if ( spitPileOne.getComponentCount() == 0 )
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	
	public boolean spitPileTwoIsEmpty()
	{
		CardSlot spitPileTwo = getSpitPileTwo();
		
		if ( spitPileTwo.getComponentCount() == 0 )
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	
    
    public synchronized void setPlayerDecksSpit(boolean status)
    {
    	playerDecksSpit = status;
    }
    
    class PickUpListener implements MouseListener
	{
				
		@Override
		public void mouseClicked(MouseEvent e) 
		{			
			
		}

		@Override
		public void mouseEntered(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mouseExited(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		
		public void mousePressed(MouseEvent e) {
			
			System.out.println(playerDecksSpit);
			
				//endGamePanel.setWon(false);
				Game.this.setGlassPane(handPanel);				

				previousSlotTouched = (CardSlot) e.getComponent();
				
				if ( previousSlotTouched.getComponentCount() > 0 )
				{
				
					cardInHand = ((CardSlot) e.getComponent()).getTopCard();
					
				
					if ( cardInHand.isFlippedToFront())
					{
				
						System.out.println("PICKING UP!");					
				
						System.out.println("card on table before pick up is " + previousSlotTouched.getTopCard());
						//cardInHand.setBounds(10, 10, cardInHand.getWidth(), cardInHand.getHeight());
				
						PointerInfo a = MouseInfo.getPointerInfo();
						Point b = a.getLocation();
						int x = (int) b.getX();
						int y = (int) b.getY();
						
						//int xx = e.getX() + gameBoard.getX();
						//int yy = e.getY() + gameBoard.getY();
				
						//holdListener = new HoldListener();
						//putDownListener = new PutDownListener();
				
						//cardInHand.addMouseMotionListener(holdListener);
						//cardInHand.addMouseListener(putDownListener);
				
						handPanel.add(cardInHand);
						Game.this.getGlassPane().setVisible(true);
				
						cardInHand.setLocation(x-40, y-60);
						if (previousSlotTouched.getComponentCount() > 0)
						{
							System.out.println("card on table after pick up is " + previousSlotTouched.getTopCard());
						}

							
						Game.this.revalidate();
						Game.this.repaint();
						
						//System.out.println("Location of player Two Deck is " + playerTwoDeck.getLocation());
						//System.out.println("Location of player Two Deck is " + playerTwoPileTwo.getLocation());
					}
					else
					{
						previousSlotTouched.flipTopCard();
					
						Game.this.revalidate();
						Game.this.repaint();
					
						cardInHand = null;
					}
				}			
			
			
			
		}

		@Override
		public void mouseReleased(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}			
		
	}
	
    class HoldListener implements MouseMotionListener
	{
    	public CardSlot cardSlotUnderMouse(MouseEvent e)
    	{
			int x = e.getX();
			int y = e.getY();
    		
    		//CardSlot cardSlotUnderMouse = null;
    		
    		for ( CardSlot playerPile : playerOnePiles)
    		{
    			System.out.println("");
    			System.out.println(x);
    			System.out.println(y);
    			System.out.println(playerPile.getLocation());
    			System.out.println(playerPile.getWidth());
    			System.out.println(playerPile.getHeight());
    			
    			if ( ( x > playerPile.getLocation().x && x < playerPile.getLocation().x+playerPile.getWidth() )
    					&& ( y > playerPile.getLocation().y && y < playerPile.getLocation().y+playerPile.getHeight() ))
    			{
    				return playerPile;
    			}
    		}
    		
    		return null;
    	}

		@Override
		public void mouseDragged(MouseEvent e) 
		{
			/*if ( cardSlotUnderMouse(e) != null )
			{
				if ( cardSlotUnderMouse(e).getComponentCount() == 0)
				{
					handPanel.removeMouseMotionListener(holdListener);
					
					cardSlotUnderMouse(e).acceptCard(cardInHand);
					
					//Game.this.revalidate();
					//Game.this.repaint();
					
					//handPanel.removeMouseListener(putDownListener);
				}
				else
				{
					handPanel.removeMouseMotionListener(holdListener);
					
					cardSlotUnderMouse(e).acceptCard(cardInHand);
					
    				//Game.this.revalidate();
					//Game.this.repaint();
					
					//handPanel.removeMouseListener(putDownListener);
				}
			}
			else
			{
				Game.this.getGlassPane().setVisible(true);
				
				if (  !( cardInHand == null ) )
				{
					int x = e.getX();
					int y = e.getY();
					
					cardInHand.setLocation(x-40, y-40);
					
					Game.this.revalidate();
				    Game.this.repaint();
				}
				
				Game.this.revalidate();
				Game.this.repaint();
			}
		/*else
		{
			if (  !( cardInHand == null ) )
			{
				int x = e.getX();
				int y = e.getY();
				
				cardInHand.setLocation(x-40, y-40);
				
				Game.this.revalidate();
			    Game.this.repaint();
			}
		}*/
			
			
		}

		@Override
		public void mouseMoved(MouseEvent e) 
		{
			
			if (  !( cardInHand == null ) )
			{
				int x = e.getX();
				int y = e.getY();
				
				cardInHand.setLocation(x-40, y-40);
				
				Game.this.revalidate();
			    Game.this.repaint();
			}
			
		}


				
	}
    
    class PutDownListener implements MouseListener
    {
    	public CardSlot playerPileUnderMouse(MouseEvent e)
    	{
			int x = e.getX();
			int y = e.getY();
    		
    		//CardSlot cardSlotUnderMouse = null;
    		
    		for ( CardSlot playerPile : playerOnePiles)
    		{
    			System.out.println("");
    			System.out.println(x);
    			System.out.println(y);
    			System.out.println(playerPile.getLocation());
    			System.out.println(playerPile.getWidth());
    			System.out.println(playerPile.getHeight());
    			
    			if ( ( x > playerPile.getLocation().x + gameBoard.getLocation().x && x < playerPile.getLocation().x+playerPile.getWidth() + gameBoard.getLocation().x )
    					&& ( y > playerPile.getLocation().y + gameBoard.getLocation().y && y < playerPile.getLocation().y+playerPile.getHeight()+ gameBoard.getLocation().y ))
    			{
 
    				if ( playerPile.getComponentCount() == 0)
    				{
    					return playerPile;
    				}
    				else if ( playerPile.topCardSameAs(cardInHand))
    				{
    					return playerPile;
    				}
    				else if ( playerPile == previousSlotTouched)
    				{
    					return playerPile;
    				}
    				else
    				{
    					return null;
    				}
       			}
    		}
    		
    		return null;
    	}
    	
    	public CardSlot spitPileUnderMouse(MouseEvent e)
    	{
			int x = e.getX();
			int y = e.getY();
    		
    		//CardSlot cardSlotUnderMouse = null;
    		
    		for ( CardSlot spitPile : spitPiles)
    		{
    			System.out.println("");
    			System.out.println(x);
    			System.out.println(y);
    			System.out.println(spitPile.getLocation());
    			System.out.println(spitPile.getWidth());
    			System.out.println(spitPile.getHeight());
    			
    			System.out.println("lol" + spitPiles.get(0).getLocation());
    			
    			if ( ( x > spitPile.getLocation().x + gameBoard.getLocation().x && x < spitPile.getLocation().x+spitPile.getWidth() + gameBoard.getLocation().x )
    					&& ( y > spitPile.getLocation().y + gameBoard.getLocation().y && y < spitPile.getLocation().y+spitPile.getHeight()+ gameBoard.getLocation().y ))
    			{
 
    				if ( spitPile.getComponentCount() == 0)
    				{
    					return null;
    				}
    				if ( spitPile.topCardRankNextTo(cardInHand))
    				{
    					return spitPile;
    				}
    				else
    				{
    					System.out.println("NOT WORKING!");
    					return null;
    				}
       			}
    		}
    		if ( ( x > spitPileThree.getLocation().x + gameBoard.getLocation().x && x < spitPileThree.getLocation().x+spitPileThree.getWidth() + gameBoard.getLocation().x )
					&& ( y > spitPileThree.getLocation().y + gameBoard.getLocation().y && y < spitPileThree.getLocation().y+spitPileThree.getHeight()+ gameBoard.getLocation().y ))
			{
				if ( spitPileThree.getComponentCount() == 0)
				{
					return null;
				}
				if ( spitPileThree.topCardRankNextTo(cardInHand))
				{
					return spitPileThree;
				}
				else
				{
					System.out.println("NOT WORKING!");
					return null;
				}
			}
    		
    		return null;
    	}

		@Override
		public void mouseClicked(MouseEvent e) {


		}

		@Override
		public void mouseEntered(MouseEvent arg0) 
		{
			
			
		}

		@Override
		public void mouseExited(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mousePressed(MouseEvent e) 
		{

            System.out.println("PUTTING DOWN!");
			
			Game.this.getGlassPane().setVisible(false);
			
			if ( playerPileUnderMouse(e) != null )
			{
				if ( playerPileUnderMouse(e).getComponentCount() == 0)
				{
					//handPanel.removeMouseMotionListener(holdListener);
					
					playerPileUnderMouse(e).acceptCard(cardInHand);
					
					//Game.this.revalidate();
					//Game.this.repaint();
					
					//handPanel.removeMouseListener(putDownListener);
				}
				else
				{
					//handPanel.removeMouseMotionListener(holdListener);
					
					playerPileUnderMouse(e).acceptCard(cardInHand);
					
					//Game.this.revalidate();
					//Game.this.repaint();
					
					//handPanel.removeMouseListener(putDownListener);
				}
			}
			else if ( playerDecksSpit && spitPileUnderMouse(e) != null )
			{
				spitPileUnderMouse(e).acceptCard(cardInHand);
				
				if ( allMyPilesAreEmpty() )
				{
					gameIsOn = false;
					
					if ( myDeckIsEmpty() && spitPileOneIsEmpty() )
					{
						bringUpEndGamePanel(true);
					}
					else
					{
						bringUpInterRoundPanel(true);
						

					}

					
					
				} 
				
			}
			else
			{
				Game.this.getGlassPane().setVisible(true);
				
				Game.this.revalidate();
				Game.this.repaint();
			}
			
			Game.this.repaint();
			
		}

		@Override
		public void mouseReleased(MouseEvent e) {
			
			
			
		}
    	
    }

	class PileChooserListener implements MouseListener
	{
	
		public CardSlot spitPileUnderMouse(MouseEvent e)
		{
			int x = e.getX();
			int y = e.getY();
			
			//CardSlot cardSlotUnderMouse = null;
			
			for ( CardSlot spitPile : spitPiles)
			{
				System.out.println("");
				System.out.println(x);
				System.out.println(y);
				System.out.println(spitPile.getLocation());
				System.out.println(spitPile.getWidth());
				System.out.println(spitPile.getHeight());
				
				System.out.println("lol" + spitPiles.get(0).getLocation());
				
				if ( ( x > spitPile.getLocation().x + gameBoard.getLocation().x && x < spitPile.getLocation().x+spitPile.getWidth() + gameBoard.getLocation().x )
						&& ( y > spitPile.getLocation().y + gameBoard.getLocation().y && y < spitPile.getLocation().y+spitPile.getHeight()+ gameBoard.getLocation().y ))
				{
					if ( spitPile.getComponentCount() > 0)
					{
						return spitPile;
					}
	

	   			}
			}
			if ( ( x > spitPileThree.getLocation().x + gameBoard.getLocation().x && x < spitPileThree.getLocation().x+spitPileThree.getWidth() + gameBoard.getLocation().x )
					&& ( y > spitPileThree.getLocation().y + gameBoard.getLocation().y && y < spitPileThree.getLocation().y+spitPileThree.getHeight()+ gameBoard.getLocation().y ))
			{

				if ( spitPileThree.getComponentCount() > 0)
				{
					return spitPileThree;
				}
				
   			}
			
			return null;
		}
		
		@Override
		public void mouseClicked(MouseEvent e) {
			// TODO Auto-generated method stub
			
		}
	
		@Override
		public void mouseEntered(MouseEvent e) {
			// TODO Auto-generated method stub
			
		}
	
		@Override
		public void mouseExited(MouseEvent e) {
			// TODO Auto-generated method stub
			
		}
	
		@Override
		public void mousePressed(MouseEvent e) {
			
			Game.this.getGlassPane().setVisible(false);
			
			if ( spitPileUnderMouse(e) != null )
			{
				addDeckToDeck(spitPileUnderMouse(e), playerOneDeck);
				playerShuffleButton.setEnabled(true);
				spitButton.setEnabled(false);
				
				for ( CardSlot spitPile : spitPiles)
				{
					for ( CardSlot pile : playerTwoPiles)
					{
						addDeckToDeck(pile, playerTwoDeck);
					}
					
					if ( spitPile != spitPileUnderMouse(e))
					{
						addDeckToDeck(spitPile, playerTwoDeck);
					}
				}
				
				interRoundPanel.removeMouseListener(pileChooserListener);
				
				playerDecksSpit = false;
				
				
			}
			else
			{
				Game.this.getGlassPane().setVisible(true);
			}
		}
	
		@Override
		public void mouseReleased(MouseEvent e) {
			// TODO Auto-generated method stub
			
		}
	
	
		
	}
	
	class VoidListener implements MouseListener
	{

		@Override
		public void mouseClicked(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mouseEntered(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mouseExited(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mousePressed(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mouseReleased(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}


		
	}

}
